<template>
  <view
    style="position: absolute; left: 0; width: 750rpx; z-index: 65536"
    :style="{ top: `${top}px`, height: `${height}px` }"
  >
    <video
      :src="src"
      :poster="poster"
      :title="title"
      :direction="directionComputed"
      @ended="ended"
      @loadedmetadata="loadedmetadata"
      @timeupdate="timeupdate"
      @waiting="waiting"
      @fullscreenchange="fullscreenchange"
      @error="error"
      @castinguserselect="castinguserselect"
      @castingstatechange="castingstatechange"
      @castinginterrupt="castinginterrupt"
      class="video"
      :controls="true"
      style="width: 100%; height: 100%; position: relative"
      :autoplay="true"
      :vslide-gesture="true"
      :vslide-gesture-in-fullscreen="true"
      :show-progress="false"
      :show-fullscreen-btn="false"
      :show-play-btn="false"
      :show-center-play-btn="false"
      :enable-play-gesture="true"
      :show-bottom-progress="false"
      :picture-in-picture-mode="['push', 'pop']"
      picture-in-picture-init-position="(left,50%)"
    >
      <slot name="default"></slot>
    </video>
  </view>
</template>

<script>
import TopInfo from "@/utils/top-info";
import ElementInfo from "@/utils/element-info";

export default {
  name: "my-video",
  props: {
    /**
     * 设置视频 url
     * @example
     * https://llg.qiniu.comeinvip.com/lhxU4my6HPSW9cFbFuyYLjhpx9lw.mp4
     */
    src: {
      type: String,
    },
    /**
     * 设置视频全屏时的方向
     * @type {'normal' | 'left' | 'right'}
     */
    direction: {
      type: String,
    },
    /**
     * 视频封面 url
     * @example
     * http://llg.qiniu.comeinvip.com/images/logo.png
     */
    poster: {
      type: String,
    },
    /**
     * 全屏显示时的视频名称
     */
    title: {
      type: String,
    },
  },
  computed: {
    /**
     * 将全屏旋转方向词映射为实际的值
     * @returns {0 | 90 | -90}
     */
    directionComputed() {
      let direction = 0;
      switch (this.direction) {
        case "normal":
          direction = 0;
          break;
        case "left":
          direction = 90;
          break;
        case "right":
          direction = -90;
          break;
        default:
          direction = 0;
          break;
      }
      return direction;
    },
  },
  data() {
    return {
      /**
       * 视频定位避开胶囊的距离
       */
      top: TopInfo.getMenuButtonBottom(),
      /**
       * 视频占据胶囊下方的全部高度
       */
      height: TopInfo.getBodyHeight(),
      /**
       * 视频自己的上下文
       */
      context: null,
    };
  },
  methods: {
    /**
     * 对外暴露的播放视频方法
     */
    play() {
      this.context.play();
    },
    /**
     * 对外暴露的暂停视频方法
     */
    pause() {
      this.context.pause();
    },
    /**
     * @typedef LoadedMetaData
     * @property {number} width 视频宽度
     * @property {number} height 视频高度
     * @property {number} duration 视频时长，单位 s
     */
    /**
     *
     * @param {LoadedMetaData} event 视频载入完成事件
     * @returns {Promise<void>}
     */
    async loadedmetadata(event) {
      let duration = event.detail.duration;
      let videoElementInfo = await ElementInfo.getElementInfo(this, ".video");
      this.context = videoElementInfo.context;
      this.$emit("loadedmetadata", { duration, context: this.context });
    },
    /**
     * 检测到视频播放到了末尾
     */
    ended() {
      this.$emit("ended");
    },
    /**
     * @typedef TimeUpdate
     * @property {number} currentTime 当前进度时间
     */
    /**
     * 视频进度改变
     * @param {TimeUpdate} event 视频进度对象
     */
    timeupdate(event) {
      this.$emit("timeupdate", event);
    },
    /**
     * 视频进入和退出全屏
     * fullScreen: 是否全屏
     * direction: 屏幕方向 vertical horizontal
     */
    /**
     * @typedef FullScreenChange
     * @property {boolean} fullScreen 是否全屏
     * @property {'vertical' | 'horizontal'} direction 屏幕方向
     */
    /**
     * 进入和退出全屏事件
     * @param {FullScreenChange} event
     */
    fullscreenchange(event) {
      this.$emit("fullscreenchange", event);
    },
    /**
     * 视频出现缓冲
     */
    waiting() {
      this.$emit("waiting");
    },
    /**
     * 视频播放出错
     */
    error() {
      this.$emit("error");
    },
    /**
     * 用户选择投屏设备
     * state: 投屏状态 success fail
     */
    castinguserselect(event) {
      this.$emit("castinguserselect", event);
    },
    /**
     * 投屏成功/失败
     * type:
     * state: success fail
     */
    castingstatechange(event) {
      this.$emit("castingstatechange", event);
    },
    /**
     * 投屏被中断
     */
    castinginterrupt(event) {
      this.$emit("castinginterrupt", event);
    },
  },
};
</script>
